package net.love5z.web.common.session;

import java.io.Serializable;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionContext;

@SuppressWarnings("deprecation")
public class GaeSession implements HttpSession, Serializable {

    private static final long        serialVersionUID          = 1L;

    private Map<String, Object>      store                     = new HashMap<String, Object>();

    private String                   gaeCacheSessionId;

    private long                     creationTime;

    private long                     lastAccessedTime;

    private int                      maxInactiveIntervalSecond = -1;

    private boolean                  isNewSession;

    private transient ServletContext sevletContext;

    private boolean                  isValid;

    GaeSession(String gaeCacheSessionId) {
        super();
        this.gaeCacheSessionId = gaeCacheSessionId;
        this.creationTime = System.currentTimeMillis();
        this.lastAccessedTime = creationTime;
        this.isNewSession = true;
        isValid = true;
    }

    public Object getAttribute(String key) {
        lastAccessedTime = System.currentTimeMillis();
        //synchronized (store)
        {
            Object v = store.get(key);
            return v;
        }
    }

    public void setAttribute(String key, Object value) {
        lastAccessedTime = System.currentTimeMillis();
        //synchronized (store)
        {
            store.put(key, value);
        }
    }

    public void removeAttribute(String key) {
        //synchronized (store)
        {
            store.remove(key);
        }
    }

    public Enumeration<String> getAttributeNames() {
        //synchronized (store)
        {
            return Collections.enumeration(store.keySet());
        }
    }

    public Object getValue(String key) {
        return getAttribute(key);
    }

    public void putValue(String key, Object value) {
        setAttribute(key, value);
    }

    public void removeValue(String key) {
        removeAttribute(key);
    }

    public String[] getValueNames() {
        lastAccessedTime = System.currentTimeMillis();
        //synchronized (store)
        {
            if (store == null) {
                return new String[0];
            }
            String[] s = new String[store.size()];
            @SuppressWarnings("rawtypes")
            Enumeration e = getAttributeNames();
            int count = 0;
            while (e.hasMoreElements()) {
                s[count++] = (String) e.nextElement();
            }
            return s;
        }
    }

    public long getCreationTime() {
        return creationTime;
    }

    public String getId() {
        return this.gaeCacheSessionId;
    }

    public long getLastAccessedTime() {
        return this.lastAccessedTime;
    }

    public int getMaxInactiveInterval() {
        if (Integer.MAX_VALUE / 2 <= maxInactiveIntervalSecond) {
            return -1;
        } else {
            return maxInactiveIntervalSecond;
        }
    }

    public void setMaxInactiveInterval(int value) {
        if (value < 0) {
            maxInactiveIntervalSecond = Integer.MAX_VALUE / 2;
        } else {
            maxInactiveIntervalSecond = value;
        }
    }

    public ServletContext getServletContext() {
        return this.sevletContext;
    }

    void setServletContext(ServletContext servletContext) {
        this.sevletContext = servletContext;
    }

    public HttpSessionContext getSessionContext() {
        return null;
    }

    void setLastAccessTime(long lastAccessedTime) {
        this.lastAccessedTime = lastAccessedTime;
    }

    void setOldInstance() {
        this.isNewSession = false;
    }

    public boolean isNew() {
        return this.isNewSession;
    }

    public boolean isValid() {
        return isValid;
    }

    public void setValid(boolean isValid) {
        this.isValid = isValid;
    }

    public void invalidate() {
        //synchronized (store)
        {
            store.clear();
        }
        setValid(false);
        //TODO gae session remove
    }

}
